
#ifndef __observableH__
#define __observableH__

#include "kernel.h"

namespace WtfEngine {
	/**
	 * Observable objects allow functors to be registered to them, which are called
	 * when the object calls its NotifyObservers method.
	 * @note Being observed does not keep and object in memory. All observer references
	 *       will be removed when the object is destroyed.
	 **/
	class IObservable: public virtual IGcObject {
		GC_INTERFACE(IObservable);

	private:
		/**
		 * Implementation of observable objects uses the event subsystem, to save memory on
		 * non-observed objects.
		 **/
		class ObservableNotifyEvent: public KeyedEvent<ObservableNotifyEvent> {
			/// Note the weak reference here - allows observables to be destroyed even
			/// when being observed.
			IObservable::tWeakRef mrObject;

		public:
			inline ObservableNotifyEvent(IObservable * const pObject)
				: KeyedEvent<ObservableNotifyEvent>(), mrObject(pObject) {
			};

			EVENT(ObservableNotifyEvent, KeyedEvent<ObservableNotifyEvent>, (
				mrObject == pEv->mrObject ? 0 : (mrObject < pEv->mrObject ? -1 : 1)
			));
			GC_AUTOSIZE(ObservableNotifyEvent);
		};

		ObservableNotifyEvent::tRef mrEvent;
		unsigned muNumObservers;


	public:
		IObservable();
		virtual ~IObservable();

		void AddObserver(const IFunctor<>::tRef& rObserver);
		void RemoveObserver(const IFunctor<>::tRef& rObserver);

		void NotifyObservers();
	};
};

#endif
